2019年12月12日
By: Chase

Do not use Array index in keys

eslint里有这么一项相关规则, 原来一直不知道为啥, 以为key unique就行了, 昨儿自己写了个简单的数组render一下, 看看key等于index和其他非重复value的区别. 先上精简版, 看懂的就不用看我的得出过程了:

图-0

图-1

以上没看懂或者存怀疑的可以看我如何得出上图的, 可以往下看代码了. 父组件:

state = {
  testArray: [
    {id: 1},
    {id: 2},
    {id: 3},
    {id: 4},
    {id: 5}
  ]
}

_deleteItem = (id) => {
  this.setState(prevState => ({
    testArray:  prevState.testArray.filter(
      item => item.id !== id)
  }))
 }
 
render() {
  return (
    <div>
      {this.state.testArray.map((item,index) => (
          <ChildDom
            key={index}      
            key={item.id}    // 此行为注释行
            id={item.id}
            onClickFunc={() => this._deleteItem(item.id)}
          />
        ))
      }  
    </div>   
  )
 }
}

子组件:

export default class ChildDom extends React.Component {
  componentDidUpdate(prevProps) {
    console.log(`thisPropsID: ${this.props.id}`)
    console.log(`prevPropsID: ${prevProps.id}`)  
  } 

  componentWillUnmount() {
    console.log(`unMount: ${this.props.id}`)
  }

  render() {
    return (
      <div>
        {this.props.id}
        <button onClick={this.props.onClickFunc}>
          delete
        </button> 
      </div>   
    )
  }
}

delete第三项, 当key = index 时, unMount的是数组的最后一个组件, 然后删除项之后的组件id值变化了, 分别向后一个元素更新, 如下图:

图-2

key = item.id时: 第三项直接自己unMount了, 其余各项id没有变化 , 如下图: 图-3

但是由于父组件render了, 子组件跟着都render了一遍, 可以用shouldComponentUpdate优化子组件render.

Tags: 前端 React